﻿using DevExpress.Utils.Extensions;
using Marmat.Foundation;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Marmat.Template.WinForm
{
    /// <summary>
    /// 基于DataTable的视图窗体的控制器
    /// </summary>
    public class DocumentViewFormController : DocumentViewFormController<System.Data.DataRow, System.Data.DataTable>, IViewFormController
    {
        /// <summary>
        /// 单据管理实例
        /// </summary>
        public virtual new DocumentManagement Management { get => (DocumentManagement)base.Management; set => base.Management = value; }
    }

    /// <summary>
    /// 基于实例的视图窗体的控制器
    /// </summary>
    /// <typeparam name="Entity"></typeparam>
    public class DocumentViewFormController<Entity> : DocumentViewFormController<Entity, Entity[]>, IDocumentViewFormController<Entity> where Entity : class, new()
    {
        /// <summary>
        /// 单据管理实例
        /// </summary>
        public virtual new DocumentManagement<Entity> Management { get => (DocumentManagement<Entity>)base.Management; set => base.Management = value; }
    }

    /// <summary>
    /// 基于实例的视图窗体的控制器
    /// </summary>
    /// <typeparam name="Entity"></typeparam>
    /// <typeparam name="Source"></typeparam>
    public class DocumentViewFormController<Entity, Source> : IDocumentViewFormController<Entity, Source>, IViewFormPagination, ISearchControlController, INotification
    {
        /// <summary>
        /// 储存上一次的搜索条件。
        /// </summary>
        private string condition;
        private int loadPage;
        private int loadTop;
        private string loadOrder;
        private Source dataSource;
        private ISearchControl searchControl;

        public DocumentViewFormController()
        {
            this.loadTop = this.GetPageSize();
        }

        /// <summary>
        /// 单据管理实例
        /// </summary>
        public virtual DocumentManagement<Entity, Source> Management { get; set; }

        bool Foundation.IViewFormController.AllowCreate { get => this.Management.AllowCreate; set => this.Management.AllowCreate = value; }

        /// <summary>
        /// 窗体面板
        /// </summary>
        public IDocumentViewForm<Entity, Source> FormPanel { get; set; }

        /// <summary>
        /// 获取已经加载的数据源。
        /// </summary>
        protected Source DataSource => dataSource;

        /// <summary>
        ///  获取或设置是否显示分页组件。
        /// </summary>
        bool IViewFormPagination.Visible => this.Management.Command is IDocumentCommandPagination<Entity, Source>;
        int IViewFormPagination.PageSize { get => this.GetPageSize(); set => new NotFiniteNumberException(); }
        int[] IViewFormPagination.PageSizes { get => this.GetPageSizes(); set => new NotFiniteNumberException(); }
        protected ISearchControl SearchControl { get => searchControl; }

        /// <summary>
        /// 获取分页模式下时，默认每页加载的记录数量。
        /// </summary>
        /// <returns></returns>
        protected virtual int GetPageSize()
        {
            return 100;
        }

        /// <summary>
        /// 每页显示个数选择器的选项设置。
        /// </summary>
        /// <returns></returns>
        protected virtual int[] GetPageSizes()
        {
            return new int[] { 20, 50, 100 };
        }

        void Foundation.IViewFormController.CreateEvent()
        {
            this.CreateEvent();
        }

        /// <summary>
        /// 在 ViewForm 窗体中点击创建按钮时触发。 通常用于打开新建页面。
        /// </summary>
        protected virtual void CreateEvent()
        {
            this.Management.ShowCreateForm();
        }

        Foundation.IViewFormController IViewFormRoute.GetController()
        {
            return this;
        }

        Control IViewFormRoute.GetViewPanel()
        {
            return this.FormPanel as Control;
        }

        /// <summary>
        /// 加载
        /// </summary>
        public void Load()
        {
            this.Load(this.condition, this.loadPage, this.loadTop, this.loadOrder);
        }

        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="condition"></param>
        public virtual void Load(string condition)
        {
            this.Load(condition, -1, int.MaxValue, "");
        }

        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="page"></param>
        /// <param name="top"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public virtual int Load(string condition, int page, int top, string order)
        {
            // 记录本次的搜索条件，便于下一次的刷新使用。
            this.condition = condition;
            this.loadPage = page;
            this.loadTop = top;
            this.loadOrder = order;

            int count = 0;
            Source result = default;
            if (this.Management.Command is IDocumentCommand<Entity, Source> command)
                result = command.Load(condition);
            else if (this.Management.Command is IDocumentCommandPagination<Entity, Source> pagination)
                result = pagination.Load(condition, page, top, order, out count);
            this.FormPanel.Load(result);
            this.dataSource = result;
            return count;
        }

        public virtual void InitializationSearchControl(ISearchControl searchControl)
        {
            this.searchControl = searchControl;
        }

        public virtual void ReceiveNotification(string channel, params object[] arguments)
        {
        }

        ///// <summary>
        ///// 使用异步加载，加载过程中并且提示用户
        ///// </summary>
        ///// <param name="condition"></param>
        ///// <param name="page"></param>
        ///// <param name="top"></param>
        ///// <param name="order"></param>
        ///// <returns></returns>
        //public int LoadAsync(string condition, int page, int top, string order)
        //{
        //    int count = 0;
        //    DataSource result = Marmat.Forms.AsyncHelper.Run(() =>
        //   {
        //       if (this.Management.Command is IDocumentCommandPagination<Entity, DataSource> pagination)
        //           return pagination.Load(condition, page, top, order, out count);
        //       else
        //           return this.Management.Command.Load(condition);
        //   });
        //    this.FormPanel.Load(result);
        //    return count;
        //}
    }
}

